package ongd.web;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import ongd.negocio.gestion.ControladorPadrino;
import ongd.negocio.gestion.ControladorSocio;
import ongd.negocio.gestion.Cuota;
import ongd.negocio.gestion.CuotaPK;
import ongd.servicios.persistencia.exceptions.IllegalOrphanException;
import ongd.servicios.persistencia.exceptions.NonexistentEntityException;
import org.primefaces.context.RequestContext;

/**
 * Clase que se encargará de listar las cuotas de los socios o padrinos que
 * no estén dados de baja.
 *
 * @author <a href="mailto:egi0002@alu.ubu.es">Elena García Iglesias</a>
 * @author <a href="mailto:cms0021@alu.ubu.es">Cristina Martínez Sanz</a>
 * @version 1.0 20120124
 *
 */
@ManagedBean
@ViewScoped
public class Listado_Cuota extends ABean {

    /**
     * Objeto del tipo controladorSocio que nos servirá para crear las
     * instancias correspondientes a la inserción de un socio.
     */
    private ControladorSocio contSocio;
    /**
     * Objeto del tipo controladorApadrinamiento que nos servirá para crear las
     * instancias correspondientes a la inserción de un padrino.
     */
    private ControladorPadrino contPadrino;
    /**
     * Objeto de tipo List que corresponde con la lista de cuotas que se
     * mostrarán por pantalla.
     */
    private List<Cuota> listaMostrar;
    /**
     * Objeto de tipo List que corresponde con la lista de cuotas que hay 
     * en la base de datos.
     */
    private List<Cuota> listaCuotas;
    /**
     * Objeto de tipo SelecItem que servirá para crear un filtro de cuotas.
     */
    private SelectItem[] estadoOptions;
    /**
     * Objeto de tipo cuotaPK que será la clave de la cuota que modificaremos.
     */
    private CuotaPK cuotaPK;
    /**
     * Objeto de tipo String que va a contener el título de la página donde
     * estemos.
     */
    private String titulo;

    /**
     * Constructor de la clase.
     */
    public Listado_Cuota() {
        listaMostrar = new ArrayList<Cuota>();
        listaCuotas = new ArrayList<Cuota>();
        estadoOptions = crearFiltroOpciones();
    }

    /**
     * Método que servirá para cargar los parámetros iniciales en función de
     * la variable pasada al cargar la página.
     */
    @Override
    public void cargaInicial() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            SesionBean sesion = getSesionBean();
            if (sesion.iniciadaSesion()) {
                //Si voy a crear un socio, me creare el controlador de socio apropiado para ello.
                if (sesion.getStrVariable().compareTo("socio") == 0) {
                    titulo = "Gestionar - Cuotas Socios";
                    contSocio = sesion.getControladorSocio();
                    listaCuotas = contSocio.obtenerListaCuotas("S");
                } else if (sesion.getStrVariable().compareTo("padrino") == 0) {
                    titulo = "Gestionar - Cuotas Padrinos";
                    contPadrino = sesion.getControladorPadrino();
                    listaCuotas = contPadrino.obtenerListaCuotas("P");
                }
                listaMostrar = cambiarEstadoCuota();
            }
        }
        //lo que se quiera hacer siempre que se pulsa un botón o hay una llamada java desde el xhtml
    }

    /**
     * Método que devuelve un objeto de tipo SelectItem que creará un filtro
     * de opciones
     * @return options
     */
    private SelectItem[] crearFiltroOpciones() {
        String[] datos = new String[3];
        datos[0] = "Pendiente";
        datos[1] = "Abonada";
        datos[2] = "Cancelada";
        SelectItem[] options = new SelectItem[datos.length + 1];
        options[0] = new SelectItem("", "Select");
        for (int i = 0; i < datos.length; i++) {
            options[i + 1] = new SelectItem(datos[i], datos[i]);
        }
        return options;
    }

    /**
     * Método que cambiará el estado "P", "A" o "C" de la lista de cuotas por
     * "Pendiente", "Abonada" y "Cancelada".
     * @return lista
     */
    private List<Cuota> cambiarEstadoCuota() {
        List<Cuota> lista = new ArrayList<Cuota>();
        for (int i = 0; i < listaCuotas.size(); i++) {
            Cuota c = listaCuotas.get(i);
            Cuota d = new Cuota();
            d.setCuotaPK(c.getCuotaPK());
            d.setCantidad(c.getCantidad());
            d.setFechaCreacion(c.getFechaCreacion());
            d.setFechaPago(c.getFechaPago());
            d.setPersona(c.getPersona());
            if (c.esAbonada()) {
                d.setEstado("Abonada");
            } else if (c.esCancelada()) {
                d.setEstado("Cancelada");
            } else if (c.esPendiente()) {
                d.setEstado("Pendiente");
            }
            lista.add(d);
        }
        return lista;
    }

    /**
     * Método que recorre la lista de cuotas obtenida en busca de una cuota
     * que tenga la misma clave.
     * @return cuota
     */
    public Cuota obtenerCuota() {
        int indice = 0;
        for (int i = 0; i < listaCuotas.size(); i++) {
            if (listaCuotas.get(i).getCuotaPK() == cuotaPK) {
                indice = i;
            }
        }
        return listaCuotas.get(indice);
    }

    /**
     * Método que modifica el estado de una cuota a pendiente.
     * @return null
     */
    public String modificarPendiente() {
        if (getSesionBean().iniciadaSesion()) {
            try {
                Cuota c = obtenerCuota();
                boolean modificada = false;
                if (contSocio != null) {
                    modificada = contSocio.editarEstadoCuota(c, "P");
                    listaCuotas = contSocio.obtenerListaCuotas("S");
                } else if (contPadrino != null) {
                    modificada = contPadrino.editarEstadoCuota(c, "P");
                    listaCuotas = contPadrino.obtenerListaCuotas("P");
                }
                c = new Cuota();
                listaMostrar = cambiarEstadoCuota();
                if (!modificada) {
                    RequestContext requestContext = RequestContext.getCurrentInstance();
                    requestContext.addCallbackParam("error", true);
                }
                modificada = false;
            } catch (IllegalOrphanException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NonexistentEntityException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * Método que modifica el estado de una cuota a abonada.
     * @return null
     */
    public String modificarAbonada() {
        if (getSesionBean().iniciadaSesion()) {
            try {
                Cuota c = obtenerCuota();
                boolean modificada = false;
                if (contSocio != null) {
                    modificada = contSocio.editarEstadoCuota(c, "A");
                    listaCuotas = contSocio.obtenerListaCuotas("S");
                } else if (contPadrino != null) {
                    modificada = contPadrino.editarEstadoCuota(c, "A");
                    listaCuotas = contPadrino.obtenerListaCuotas("P");
                }
                c = new Cuota();
                listaMostrar = cambiarEstadoCuota();
                if (!modificada) {
                    RequestContext requestContext = RequestContext.getCurrentInstance();
                    requestContext.addCallbackParam("error", true);
                }
                modificada = false;
            } catch (IllegalOrphanException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NonexistentEntityException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * Método que modifica el estado de una cuota a cancelada.
     * @return null
     */
    public String modificarCancelada() {
        if (getSesionBean().iniciadaSesion()) {
            try {
                Cuota c = obtenerCuota();
                Boolean modificada = false;
                if (contSocio != null) {
                    modificada = contSocio.editarEstadoCuota(c, "C");
                    listaCuotas = contSocio.obtenerListaCuotas("S");
                } else if (contPadrino != null) {
                    modificada = contPadrino.editarEstadoCuota(c, "C");
                    listaCuotas = contPadrino.obtenerListaCuotas("P");
                }
                c = new Cuota();
                listaMostrar = cambiarEstadoCuota();
                if (!modificada) {
                    RequestContext requestContext = RequestContext.getCurrentInstance();
                    requestContext.addCallbackParam("error", true);
                }
                modificada = false;
            } catch (IllegalOrphanException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NonexistentEntityException ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Listado_Cuota.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * Método que obtiene un objeto de tipo SelectItem.
     * @return estadoOptions
     * @see #setEstadoOptions
     */
    public SelectItem[] getEstadoOptions() {
        return estadoOptions;
    }

    /**
     * Método que establece un objeto del tipo SelectItem.
     * @param estadoOptions Nuevo valor de la variable
     * @see #getEstadoOptions
     */
    public void setEstadoOptions(SelectItem[] estadoOptions) {
        this.estadoOptions = estadoOptions;
    }

    /**
     * Método que devuelve una lista de cuotas.
     * @return listaMostrar
     * @see #setListaMostrar
     */
    public List<Cuota> getListaMostrar() {
        return listaMostrar;
    }

    /**
     * Método que establce una lista de cuotas.
     * @param listaMostrar Nuevo valor de la variable
     * @see #getListaMostrar
     */
    public void setListaMostrar(List<Cuota> listaMostrar) {
        this.listaMostrar = listaMostrar;
    }

    /**
     * Método que devuelve un objeto del tipo CuotaPK.
     * @return cuotaPK
     * @see #setCuotaPK
     */
    public CuotaPK getCuotaPK() {
        return cuotaPK;
    }

    /**
     * Método que establece un objeto del tipo CuotaPK.
     * @param cuotaPK Nuevo valor de la variable
     * @see #getCuotaPK
     */
    public void setCuotaPK(CuotaPK cuotaPK) {
        this.cuotaPK = cuotaPK;
    }

    /**
     * Método que devuelve el valor de la variable titulo.
     * @return titulo
     * @see #setTitulo
     */
    public String getTitulo() {
        return titulo;
    }

    /**
     * Método que establece el valor de la variable título.
     * @param titulo Nuevo valor de la variable
     * @see #getTitulo
     */
    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
}